<?php

namespace App\Models;

use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;

/**
 * 新书线下直接荐购模块
 * Class NewsBookModel
 * @package app\common\model
 */
class BookHomeOfflineRecom extends BaseModel
{



    /**
     * 判断新书线下借阅权限
     * @param string $user_id 用户id
     * @param string $book_id 书籍id
     */
    public function  checkNewBookOfflineRecomBorrowAuth($account_id, $book_id)
    {
        //获取书籍信息
        $book_info = $this->getBookInfo($book_id, ['book_name', 'price', 'pre_time', 'isbn', 'shop_id', 'number']);
        if (empty($book_info)) {
            throw new \Exception('书籍信息不能为空');
        }

        //判断此书是否在采购流程中
        $this->checkPurchaseIng($book_info);
        //判断图书馆采购金额是否上限
        $this->checkPurchaseBudget($book_info);
        //相同书籍可存在数量
        $this->checkDuplicateNumber($book_info);
        //判断书籍年限上限
        $this->checkNotAllowYear($book_info);
        //判断单本书籍最大金额
        $this->checkOneMoney($book_info);
        //判断单次采购金额上限
        $this->checkPersonTimeMoney($book_info);
        //判断单次采购本书上限
        $this->checkPersonTimeNumber();
        //获取读者证号信息
        $account_lib_info = UserLibraryInfo::where('id', $account_id)->first();

        //判断读者是否有书逾期未归还或归还后
        //$this->checkReaderPurchaseState($account_id);
        //判断读者在图书馆 和 本地荐购是否有逾期金额未缴纳
        //$this->checkReaderOverdueMoney($account_id);

        //判断当前书籍是否已经采购过
        $this->checkNowIsPurchase($book_info, $account_id);
        //判断每月采购金额上限
        $this->checkPersonMonthMoney($book_info, $account_lib_info);
        //判断每月采购本书上限
        $this->checkPersonMonthNumber($account_lib_info);
        //判断每年采购金额上限
        $this->checkPersonYearMoney($book_info, $account_lib_info);
        //判断每年采购本书上限
        $this->checkPersonYearNumber($account_lib_info);
        //判断读者在图书馆借阅权限
        $this->validateBorrowLibSystem($book_info, $account_lib_info);
        return ['book_id' => $book_id, 'account_id' => $account_id, 'account' => $account_lib_info['account']];
    }


    /**
     * 判断当前书籍本数，是否在邮费设置的上限内
     */
    public function checkPostageSet($book_id)
    {
        $postage_count = BookHomePurchaseSet::count();
        if (count($book_id) > $postage_count) {
            throw new \Exception('当前书籍本数，超过单次最大借阅量，不允许采购');
        }
    }
    /**
     * 判断图书馆采购金额是否上限
     */
    public function checkPurchaseBudget($book_info)
    {
        $price = $book_info['price'];

        $bookHomePurchaseSetModel = new BookHomePurchaseSet();
        $purchase_budget = $bookHomePurchaseSetModel->where('type', 1)->value('number');
        $already_purchase_money = $bookHomePurchaseSetModel->getBookHomePurchaseMoney();
        if (($purchase_budget - $already_purchase_money) < $price) {
            throw new \Exception('图书采购预算已达上限不允许采购');
        }
    }
    /**
     * 判断书籍复本数
     */
    public function checkDuplicateNumber($book_info)
    {
        $duplicate_number = BookHomePurchaseSet::where('type', 10)->value('number');
        $bookHomeOrderModelObj = new BookHomeOrder();
        $controllerObj = new Controller();
        $libApi = $controllerObj->getLibApiObj();
        $res = $libApi->getBookInfo($book_info['isbn']);
        $num = 0;
        if ($res['code'] == 200) {
            foreach ($res['content']['data'] as $v) {
                $num += $v['holding_num'];
            }
            if ($num >= $duplicate_number) {
                //throw new \Exception('isbn为：' . $book_info['isbn'] . ' 的书籍已达到图书馆复本数上限，不允许采购');
                throw new \Exception('《' . cut_str($book_info['book_name'], 5) . '》 已达到图书馆复本数上限，不允许采购');
            }
        }
        //获取已采购的书籍本数
        $result = $bookHomeOrderModelObj->from($bookHomeOrderModelObj->getTable() . ' as o')
            ->join('book_home_order_book as b', 'b.order_id', '=', 'o.id')
            ->join('shop_book as s', 's.id', '=', 'b.book_id')
            ->where('s.isbn', $book_info['isbn'])
            ->where(function ($query) {
                $query->orwhere('o.is_pay', 1)
                    ->orwhere('o.is_pay', 2)
                    ->orwhere('o.is_pay', 6);
                //->orwhere('o.is_pay', 8);
            })->count();

        $num += $result;

        if ($num >= $duplicate_number) {
            //  throw new \Exception('isbn为：' . $book_info['isbn'] . ' 的书籍已达到图书馆复本数上限，不允许采购');
            throw new \Exception('《' . cut_str($book_info['book_name'], 5) . '》 已达到图书馆复本数上限，不允许采购');
        }
    }
    /**
     * 判断书籍年限上限
     */
    public function checkNotAllowYear($book_info)
    {
        $not_allow_year = BookHomePurchaseSet::where('type', 11)->value('number');
        if (!empty($not_allow_year)) {
            if (mb_strlen($book_info['pre_time']) > 4) {
                if ((int)mb_substr($book_info['pre_time'], 0, 4) < $not_allow_year) {
                    throw new \Exception('当前书籍出版年限不允许采购');
                }
            }
        }
    }

    /**
     * 判断单本书籍最大金额上限
     */
    public function checkOneMoney($book_info)
    {
        $one_money = BookHomePurchaseSet::where('type', 9)->value('number');
        if (empty($one_money)) {
            throw new \Exception('单本书籍最大金额设置不正确，请联系管理员处理');
        }
        if ($book_info['price'] > $one_money) {
            throw new \Exception('《' . cut_str($book_info['book_name'], 5) . '》 书籍金额，超过最大金额限制，不允许采购');
        }
    }

    /**
     * 判断单次采购金额上限
     */
    public function checkPersonTimeMoney($book_info)
    {
        $time_money = BookHomePurchaseSet::where('type', 4)->value('number');

        $price = $book_info['price'];

        if ($time_money < $price) {
            throw new \Exception('单次采购金额达到上限，不允许采购');
        }
    }
    /**
     * 判断单次采购本书上限
     */
    public function checkPersonTimeNumber()
    {
        $one_number = BookHomePurchaseSet::where('type', 3)->value('number');

        if ($one_number < 1) {
            throw new \Exception('单次采购本数达到上限，不允许采购');
        }
    }

    /**
     * 判断读者是否有书逾期未归还或归还后
     */
    public function checkReaderPurchaseState($account_id)
    {
        //判断是否有书逾期未归还
        $res = BookHomePurchase::where('account_id', $account_id)
            ->where('expire_time', '<', date('Y-m-d H:i:s'))
            ->where('return_state', '<>', 2)
            ->first();

        if ($res) {
            throw new \Exception('您之前采购的书存在逾期未归还的情况，暂不允许采购');
        }
        //判断是否归还后未处理逾期金额  在 checkReaderOverdueMoney 已经处理了
        /* BookHomePurchase();here('account_id' , $account_id)
            ->where('return_state' , 2)
            ->where('is_pay' , 3)
            ->first();

        if($res){
            throw new \Exception('您之前采购的书存在逾期未缴费的情况，暂不允许采购');
        }*/
    }

    /**
     * 判断读者是否有书逾期未归还或归还后
     */
    public function checkReaderOverdueMoney($account_id)
    {
        //判断是否有书逾期未归还
        $account_info = UserLibraryInfo::get($account_id);

        if (empty($account_info)) {
            throw new \Exception('读者信息获取失败');
        }

        if (!empty($account_info['diff_money']) && $account_info['diff_money'] != '0.00') {
            throw new \Exception('您在图书馆，存在欠费情况，暂不允许采购');
        }
        if (!empty($account_info['recom_diff_money']) && $account_info['recom_diff_money'] != '0.00') {
            throw new \Exception('您在书店采购的图书，存在欠费情况，暂不允许采购');
        }
    }
    /**
     * 判断当前书籍是否已经采购过
     */
    public function checkNowIsPurchase($book_info, $account_id)
    {
        $bookHomePurchaseModel = new BookHomePurchase();
        $bookHomeOrderModel = new BookHomeOrder();

        $res = $bookHomePurchaseModel->where('isbn', $book_info['isbn'])->where('account_id', $account_id)->count();

        if ($res >= 1) {
            //throw new \Exception('isbn:' . $book_info['isbn'] . ',此书籍已采购，不允许重复采购');
            throw new \Exception('《' . cut_str($book_info['book_name'], 5) . '》 此书籍已采购，不允许重复采购');
        }

        $result = $bookHomeOrderModel->from($bookHomeOrderModel->getTable() . ' as o')
            ->select(['o.is_pay'])
            ->join('book_home_order_book as b', 'b.order_id', '=', 'o.id')
            ->join('shop_book as s', 's.id', '=', 'b.book_id')
            ->where('s.isbn', $book_info['isbn'])
            ->where('o.type', 1) //解决新书和馆藏书id相同的bug
            ->where('o.account_id', $account_id)
            ->where(function ($query) {
                $query->orwhere('o.is_pay', 1)
                    ->orwhere('o.is_pay', 2)
                    ->orwhere('o.is_pay', 6)
                    ->orwhere('o.is_pay', 8);
            })->first();


        if ($result) {
            $msg = $result['is_pay'] == 1 ? '支付' : '查看';
            //throw new \Exception('isbn:' . $book_info['isbn'] . ',此书已经在采购流程中 请到个人中心-物流订单' . $msg);
            throw new \Exception('《' . cut_str($book_info['book_name'], 5) . '》 此书已经在采购流程中 请到个人中心-物流订单' . $msg);
        }
    }



    /**
     * 判断每月采购金额上限
     */
    public function checkPersonMonthMoney($book_info, $account_lib_info)
    {
        $month_money = BookHomePurchaseSet::where('type', 6)->value('number');
        if (empty($month_money)) {
            throw new \Exception('每月可采购金额设置不正确，请联系管理员处理');
        }
        if ($account_lib_info['last_mmm'] == date('Ym')) {

            $price = $book_info['price'];
            $price += $account_lib_info['last_money']; //加上本月采购金额
            if ($price > $month_money) {
                throw new \Exception('本月可采购金额已达上限，请联系管理员处理');
            }
        }
    }
    /**
     * 判断每月采购本书上限
     */
    public function checkPersonMonthNumber($account_lib_info)
    {
        $month_number = BookHomePurchaseSet::where('type', 5)->value('number');
        if (empty($month_number)) {
            throw new \Exception('每月可采购本数设置不正确，请联系管理员处理');
        }
        if ($account_lib_info['last_mmm'] == date('Ym')) {

            $count = $account_lib_info['last_num'] + 1; //加上本月采购金额
            if ($count > $month_number) {
                throw new \Exception('本月可采购本数已达上限，请联系管理员处理');
            }
        }
    }

    /**
     * 判断每年采购金额上限
     */
    public function checkPersonYearMoney($book_info, $account_lib_info)
    {
        $year_money = BookHomePurchaseSet::where('type', 8)->value('number');

        if (empty($year_money)) {
            throw new \Exception('每年可采购金额设置不正确，请联系管理员处理');
        }

        if ($account_lib_info['e_time'] >= date('Ym')) {
            $price = $book_info['price'];
            $price += $account_lib_info['recomed_money']; //加上本年采购金额

            if ($price > $year_money) {
                throw new \Exception('本年可采购金额已达上限，请联系管理员处理');
            }
        }
    }

    /**
     * 判断每年采购本书上限
     */
    public function checkPersonYearNumber($account_lib_info)
    {
        $year_number = BookHomePurchaseSet::where('type', 7)->value('number');
        if (empty($year_number)) {
            throw new \Exception('每年可采购本数设置不正确，请联系管理员处理');
        }

        if ($account_lib_info['e_time'] >= date('Ym')) {

            $count = $account_lib_info['recomed_num'] + 1; //加上本年采购本数
            if ($count > $year_number) {
                throw new \Exception('本年可采购本数已达上限，请联系管理员处理');
            }
        }
    }

    /**
     * 判断读者在图书馆借阅权限（新书判断）新书都是“非一卡通”书籍
     */
    public function validateBorrowLibSystem($book_info, $account_info)
    {
        //最后判断读者借阅权限
        $controllerObj = new Controller();
        $libApi = $controllerObj->getLibApiObj();

        $res = $libApi->validateBorrow($account_info['account']);
        if ($res['code'] != 200) {
            throw new \Exception($res['msg']);
        }

        //自己判断借阅本书是否上限
        $result = $libApi->getReaderInfo($account_info['account']); //获取读者借阅本书
        if ($result['code'] != 200) {
            throw new \Exception($result['msg']);
        }

        $num = $result['content']['readerBorrowInfo']['ableBorrowNum'] - 1;

        if ($num < 0) {
            throw new \Exception('此次借阅书籍本数过多，超过用户借阅上限，暂不允许借阅');
        }
        $bookHomeOrderModel = new BookHomeOrder();
        //查询用户在借阅流程中的数据本数
        $borrowing_data = $bookHomeOrderModel->select(['id', 'type'])
            ->where('account_id', $account_info['id'])
            ->where(function ($query) {
                $query->orwhere('is_pay', 1)
                    ->orwhere('is_pay', 2)
                    ->orwhere('is_pay', 6);
            })->get();

        $borrowing_able_borrow_num = 0;

        $libBookBarcodeModel = new LibBookBarcode();
        $bookHomeOrderBookModel = new BookHomeOrderBook();
        foreach ($borrowing_data as $key => $val) {
            $book_home_order_book_data = $bookHomeOrderBookModel->select(['type', 'barcode_id'])->where('order_id', $val['id'])->get();
            foreach ($book_home_order_book_data as $k => $v) {
                //新书为非一卡通
                if ($v['type'] == 1) {
                    $borrowing_able_borrow_num++;
                } else {
                    $barcode = $libBookBarcodeModel->where('id', $v['barcode_id'])->value('barcode');

                    //验证当前条形码 是一卡通还是非一卡通
                    $barcode_info = $libApi->getAssetByBarcode($barcode);
                    if ($barcode_info['code'] === 200) {
                        //ecardflag 为1 则为一卡通。其它情况为非一卡通。没返回就是 非一卡通
                        if (!isset($barcode_info['content']['ecardFlag']) || $barcode_info['content']['ecardFlag'] != 1) {
                            $borrowing_able_borrow_num++;
                        }
                    } else {
                        throw new \Exception('数据获取失败'); //第一个失败就全部失败
                    }
                }
            }
        }

        $num -= $borrowing_able_borrow_num;
        if ($num < 0) {
            throw new \Exception('申请借阅书籍本数过多，超过用户借阅上限，请等待后台管理员审核');
        }
    }

    /**
     * 判断此数据是否在采购流程中
     */
    public function checkPurchaseIng($book_info)
    {
        $obj = new BookHomePurchase();
        $res = $obj->where('isbn', $book_info['isbn'])->where(function ($query) {
            $query->orwhere('is_pay', 1)
                ->orwhere('is_pay', 2)
                ->orwhere('is_pay', 6);
        })->first();
        if ($res) {
            //  throw new \Exception('isbn：【' . $book_info['isbn'] . '】，已有用户提交申请，暂不允许借阅');
            throw new \Exception('《' . cut_str($book_info['book_name'], 5) . '》 已有用户提交申请，暂不允许借阅');
        }
    }

    /**
     * 根据书籍id 获取书店id
     * @param $book_id 书籍id   多个逗号拼接
     */
    public function getBookInfo($book_id, $field)
    {
        return ShopBook::select($field)->find($book_id);
    }
}
